package org.lib.servicehi;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.commons.security.AccessTokenContextRelay;
import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;

import feign.RequestInterceptor;

/**
 * 配置Oauth2 Client
 * @author ben
 * @date 2021-10-21 20:44:04 CST
 */
@EnableOAuth2Client
@EnableConfigurationProperties
@Configuration
public class Oauth2ClientConfig {

	/**
	 * 配置受保护的资源的信息
	 * @author ben
	 * @date 2021-10-21 20:51:43 CST
	 * @return
	 */
	@Bean
	@ConfigurationProperties(prefix = "security.oauth2.client")
	public ClientCredentialsResourceDetails clientCredentialsResourceDetails() {
		return new ClientCredentialsResourceDetails();
	}
	
	/**
	 * 配置一个过滤器：
	 * 存储当前请求和上下文
	 * @author ben
	 * @date 2021-10-21 20:52:04 CST
	 * @return
	 */
	@Bean
	public RequestInterceptor oauth2FeignRequestInterceptor() {
		return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), 
				clientCredentialsResourceDetails());
	}
	
	/**
	 * 在Request域内创建AccessTokenRequest类型的Bean
	 * @author ben
	 * @date 2021-10-21 20:52:25 CST
	 * @return
	 */
	@Bean
	public OAuth2RestTemplate clientCredentialsRestTemplate() {
		return new OAuth2RestTemplate(clientCredentialsResourceDetails());
	}

	// 解决 accessTokenContextRelay 冲突问题，还需探索 TODO
	// 见 配置
	
	@Autowired
	private OAuth2ClientContext oauth2ClientContext;
	
	/**
	 * 重新实现一个 org.springframework.cloud.commons.security.AccessTokenContextRelay Bean
	 * 名称后加 2，避免冲突
	 * @author ben
	 * @date 2021-10-22 16:57:15 CST
	 * @return
	 */
	@Bean
	public AccessTokenContextRelay accessTokenContextRelay2() {
		return new AccessTokenContextRelay(oauth2ClientContext);
	}
	
	// ---
	
}
